﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Collections;
using System.IO;
using System.Drawing;

namespace AutoMouseClick
{
    public struct ProgramSetting
    {
        public string taskInterval;
        public string clickIntervalDefault;
    }

    public struct TaskLogin
    {
        public string name;
        public string webAddress;
        public string usrName_Pos;
        public string usrName;
        public string pass;
        public string login_Pos;
        public string logout_Pos;
    }

    public struct TaskLevel1
    {
        public string name;
        public string PosName;
        public string ClickNumber;
        public string ClickInterval;
        public string ClickOffset;
        public string ClickOffsetNumber;
        //for don't parse
        public int clickNumber;
        public int clickInterval;
        public int clickOffset;
        public int clickOffsetNumber;
    }

    public struct TaskLevel2
    {
        public string name;
        public ArrayList arrTskLvl1;
        public string arrTskLvl1_Count;
        public int arrTskLvl1_count;
    }

    public struct TaskLevel3
    {
        public string name;
        public ArrayList arrTskLvl2;
        public string arrTskLvl2_Count;
        public int arrTskLvl2_count;
    }

    public struct TaskLevel4
    {
        public string name;
        public ArrayList arrTskLvl3;
        public string arrTskLvl3_Count;
        public int arrTskLvl3_count;
        public bool isNormal;
    }

    class DataWareHouse
    {
        private DataTable dt = new DataTable();
        private TaskLogin tskLogin = new TaskLogin();
        private int tskLoginIdx = -1;
        private ArrayList lst_TskLvl1 = new ArrayList();
        private ArrayList lst_TskLvl2 = new ArrayList();
        private ArrayList lst_TskLvl3 = new ArrayList();
        private ArrayList lst_TskLvl4 = new ArrayList();
        private ArrayList lst_TskCopied = new ArrayList();
        private string runNumber = "1";
        private const string FILENAME = "Database.txt";
        private const string BLACKLISTFILENAME = "BlackList.txt";
        private const string WHITELISTFILENAME = "WhiteList.txt";
        private const string LOGFOLDER = "../LOG"; 
        private ProgramSetting progSets = new ProgramSetting();
        private Hashtable blackListHash = new Hashtable();
        private Hashtable whiteListHash = new Hashtable();
        private FileStream logFs;
        private StreamWriter logWr;
        private int currLogDay = -1;

        public DataWareHouse()
        {
            //Create datatable
            DataColumn dtCol;
            DataColumn[] key = new DataColumn[1];

            dtCol = new DataColumn("Tên Tọa Độ");
            dtCol.DataType = System.Type.GetType("System.String");
            dt.Columns.Add(dtCol);
            key[0] = dtCol;

            dtCol = new DataColumn("X,Y");
            dtCol.DataType = System.Type.GetType("System.String");
            dt.Columns.Add(dtCol);

            dtCol = new DataColumn("X_Code");
            dtCol.DataType = System.Type.GetType("System.Int32");
            dt.Columns.Add(dtCol);

            dtCol = new DataColumn("Y_X");
            dtCol.DataType = System.Type.GetType("System.Int32");
            dt.Columns.Add(dtCol);

            dtCol = new DataColumn("Y");
            dtCol.DataType = System.Type.GetType("System.Int32");
            dt.Columns.Add(dtCol);

            dtCol = new DataColumn("A");
            dtCol.DataType = System.Type.GetType("System.Int32");
            dt.Columns.Add(dtCol);

            dtCol = new DataColumn("R");
            dtCol.DataType = System.Type.GetType("System.Int32");
            dt.Columns.Add(dtCol);

            dtCol = new DataColumn("G");
            dtCol.DataType = System.Type.GetType("System.Int32");
            dt.Columns.Add(dtCol);

            dtCol = new DataColumn("B");
            dtCol.DataType = System.Type.GetType("System.Int32");
            dt.Columns.Add(dtCol);

            dtCol = new DataColumn("Link");
            dtCol.DataType = System.Type.GetType("System.String");
            dt.Columns.Add(dtCol);            

            dt.PrimaryKey = key;
            dt.Rows.Clear();

            progSets.taskInterval = "2000";
            progSets.clickIntervalDefault = "200";
            //empty row
            //DataRow dtRow = dt.NewRow();
            //dtRow[0] = "";
            //dtRow[1] = "";
            //dt.Rows.Add(dtRow);

            
        }

        public DataTable DT
        {
            get
            {
                return dt;
            }
        }

        public TaskLogin TSKLOGIN
        {
            get
            {
                return tskLogin;
            }
        }

        public ArrayList LST_TSKLVL1
        {
            get
            {
                return lst_TskLvl1;
            }
            set
            {
                lst_TskLvl1 = value;
            }
        }

        public ArrayList LST_TSKLVL2
        {
            get
            {
                return lst_TskLvl2;
            }
            set
            {
                lst_TskLvl2 = value;
            }
        }

        public ArrayList LST_TSKLVL3
        {
            get
            {
                return lst_TskLvl3;
            }
        }

        public ArrayList LST_TSKLVL4
        {
            get
            {
                return lst_TskLvl4;
            }
        }

        public ArrayList LST_TSKCOPIED
        {
            get
            {
                return lst_TskCopied;
            }
        }

        public String RUNNUMBER
        {
            get
            {
                return runNumber;
            }
            set
            {
                runNumber = value;
            }
        }

        public ProgramSetting PROGSETS
        {
            get
            {
                return progSets;
            }
            set
            {
                progSets = value;
            }
        }

        public int TASKLOGININDEX
        {
            get
            {
                return tskLoginIdx;
            }
            set
            {
                tskLoginIdx = value;
            }
        }

        public Hashtable BLACKLISTHASH
        {
            get
            {
                return blackListHash;
            }
        }

        public Hashtable WHITELISTHASH
        {
            get
            {
                return whiteListHash;
            }
        }

        public void Add(string PosName, string xy)
        {
            DataRow dtRow = dt.NewRow();
            dtRow[0] = PosName;
            dtRow[1] = xy;
            string[] xpSplit = xy.Split(',');
            switch (xpSplit.Length)
            {
                case 2:
                    dtRow[2] = int.Parse(xpSplit[0]); //X
                    dtRow[3] = int.Parse(xpSplit[1]); //Y
                    dtRow[4] = 0; //NULL
                    dtRow[5] = 0; //NULL
                    dtRow[6] = 0; //NULL
                    dtRow[7] = 0; //NULL
                    dtRow[8] = 0; //NULL
                    break;
                case 3:
                    dtRow[2] = int.Parse(xpSplit[0]); //Code
                    dtRow[3] = int.Parse(xpSplit[1]); //X
                    dtRow[4] = int.Parse(xpSplit[2]); //Y
                    break;
                case 4:
                    dtRow[2] = int.Parse(xpSplit[0]); //Code
                    dtRow[3] = int.Parse(xpSplit[1]); //X
                    dtRow[4] = int.Parse(xpSplit[2]); //Y
                    dtRow[9] = xpSplit[3];//link
                    break;
                case 5:
                    dtRow[2] = int.Parse(xpSplit[0]); //Code
                    dtRow[3] = 0; //NULL
                    dtRow[4] = 0; //NULL
                    dtRow[5] = int.Parse(xpSplit[1]); //A
                    dtRow[6] = int.Parse(xpSplit[2]); //R
                    dtRow[7] = int.Parse(xpSplit[3]); //G
                    dtRow[8] = int.Parse(xpSplit[4]); //B
                    break;
                case 7:
                    dtRow[2] = int.Parse(xpSplit[0]); //Code
                    dtRow[3] = int.Parse(xpSplit[1]); //X
                    dtRow[4] = int.Parse(xpSplit[2]); //Y
                    dtRow[5] = int.Parse(xpSplit[3]); //A
                    dtRow[6] = int.Parse(xpSplit[4]); //R
                    dtRow[7] = int.Parse(xpSplit[5]); //G
                    dtRow[8] = int.Parse(xpSplit[6]); //B
                    break;
                default:
                    break;
            }
            dt.Rows.Add(dtRow);            
        }

        public void Insert(int idx, string PosName, string xy)
        {
            DataRow dtRow = dt.NewRow();
            dtRow[0] = PosName;
            dtRow[1] = xy;
            string[] xpSplit = xy.Split(',');
            switch(xpSplit.Length)
            {
                case 2:
                    dtRow[2] = int.Parse(xpSplit[0]); //X
                    dtRow[3] = int.Parse(xpSplit[1]); //Y
                    dtRow[4] = 0; //NULL
                    dtRow[5] = 0; //NULL
                    dtRow[6] = 0; //NULL
                    dtRow[7] = 0; //NULL
                    dtRow[8] = 0; //NULL
                    break;
                case 3:
                    dtRow[2] = int.Parse(xpSplit[0]); //Code
                    dtRow[3] = int.Parse(xpSplit[1]); //X
                    dtRow[4] = int.Parse(xpSplit[2]); //Y
                    break;
                case 4:
                    dtRow[2] = int.Parse(xpSplit[0]); //Code
                    dtRow[3] = int.Parse(xpSplit[1]); //X
                    dtRow[4] = int.Parse(xpSplit[2]); //Y
                    dtRow[9] = xpSplit[3];//link
                    break;
                case 5:
                    dtRow[2] = int.Parse(xpSplit[0]); //Code
                    dtRow[3] = int.Parse(xpSplit[1]); //A
                    dtRow[4] = int.Parse(xpSplit[2]); //R
                    dtRow[5] = int.Parse(xpSplit[3]); //G
                    dtRow[6] = int.Parse(xpSplit[4]); //B
                    dtRow[7] = 0; //NULL
                    dtRow[8] = 0; //NULL
                    break;
                case 7:
                    dtRow[2] = int.Parse(xpSplit[0]); //Code
                    dtRow[3] = int.Parse(xpSplit[1]); //X
                    dtRow[4] = int.Parse(xpSplit[2]); //Y
                    dtRow[5] = int.Parse(xpSplit[3]); //A
                    dtRow[6] = int.Parse(xpSplit[4]); //R
                    dtRow[7] = int.Parse(xpSplit[5]); //G
                    dtRow[8] = int.Parse(xpSplit[6]); //B
                    break;
                default:
                    break;
            }
            dt.Rows.InsertAt(dtRow,idx);
        }

        public void Delete(int idx)
        {
            dt.Rows[idx].Delete();
        }

        public TaskLevel1 GetTaskLevel1(int idx)
        {
            return (TaskLevel1)lst_TskLvl1[idx];
        }

        public TaskLevel2 GetTaskLevel2(int idx)
        {
            return (TaskLevel2)lst_TskLvl2[idx];
        }

        public TaskLevel3 GetTaskLevel3(int idx)
        {
            return (TaskLevel3)lst_TskLvl3[idx];
        }
        
        public TaskLevel4 GetTaskLevel4(int idx)
        {
            return (TaskLevel4)lst_TskLvl4[idx];
        }

        public TaskLogin GetTaskLogin(int idx)
        {
            return (TaskLogin)lst_TskLvl4[idx];
        }

        public void SetProgramSettings(string clickInterval, string taskInterval)
        {
            progSets.taskInterval = taskInterval;
            progSets.clickIntervalDefault = clickInterval;
        }

        public void ClearTaskLevel1()
        {
            lst_TskLvl1 = new ArrayList();
        }

        public void ClearTaskLevel2()
        {
            lst_TskLvl2 = new ArrayList();
        }

        public void ClearTaskLevel3()
        {
            lst_TskLvl3 = new ArrayList();
        }

        public void ClearTaskLevel4()
        {
            lst_TskLvl4 = new ArrayList();
        }

        public void ClearTaskCopied()
        {
            lst_TskCopied.Clear();
        }

        private void CreateTaskLogin(string name, string webAddress, string usrname_Pos, string usrname, string pass, string login_Pos, string logout_Pos)
        {
            tskLogin.name = name;
            tskLogin.webAddress = webAddress;
            tskLogin.usrName_Pos = usrname_Pos;
            tskLogin.usrName = usrname;
            tskLogin.pass = pass;
            tskLogin.login_Pos = login_Pos;
            tskLogin.logout_Pos = logout_Pos;
        }

        public void ExportLoginInfo(string name, string webAddress, string usrname_Pos, string usrname, string pass, string login_Pos, string logout_Pos)
        {
            CreateTaskLogin(name, webAddress, usrname_Pos, usrname, pass, login_Pos, logout_Pos);

            tskLoginIdx = lst_TskLvl4.Count;
            lst_TskLvl4.Add(tskLogin);
        }

        public void ModifyLoginInfo(int idx,string name, string webAddress, string usrname_Pos, string usrname, string pass, string login_Pos, string logout_Pos)
        {
            lst_TskLvl4.RemoveAt(idx);
            CreateTaskLogin(name, webAddress, usrname_Pos, usrname, pass, login_Pos, logout_Pos);

            lst_TskLvl4.Insert(idx,tskLogin);
        }

        public void MoveTaskLogin(int idxForm, int idxTo)
        {
            TaskLogin tsklvl4 = (TaskLogin)lst_TskLvl4[idxForm];
            lst_TskLvl4.RemoveAt(idxForm);
            lst_TskLvl4.Insert(idxTo, tsklvl4);
            tskLoginIdx = idxTo;
        }

        private TaskLevel1 CreateTaskLevel1(string name, string posName, string clickNumber, string clickInterval, string clickOffset, string clickOffsetNumber)
        {
            TaskLevel1 tskLvl1 = new TaskLevel1();
            tskLvl1.name = name;
            tskLvl1.PosName = posName;
            tskLvl1.ClickNumber = clickNumber;
            int.TryParse(clickNumber, out tskLvl1.clickNumber);

            tskLvl1.ClickInterval = clickInterval;
            int.TryParse(clickInterval, out tskLvl1.clickInterval);

            tskLvl1.ClickOffset = clickOffset;
            int.TryParse(clickOffset, out tskLvl1.clickOffset);

            tskLvl1.ClickOffsetNumber = clickOffsetNumber;
            int.TryParse(clickOffsetNumber, out tskLvl1.clickOffsetNumber);

            return tskLvl1;
        }

        public void ExportTaskLevel1(string name, string posName, string clickNumber, string clickInterval, string clickOffset, string clickOffsetNumber)
        {
            TaskLevel1 tskLvl1 = CreateTaskLevel1(name, posName, clickNumber, clickInterval, clickOffset, clickOffsetNumber);

            lst_TskLvl1.Add(tskLvl1);
        }

        public void ModifyTaskLevel1(int idx, string name, string posName, string clickNumber, string clickInterval, string clickOffset, string clickOffsetNumber)
        {
            lst_TskLvl1.RemoveAt(idx);
            TaskLevel1 tskLvl1 = CreateTaskLevel1(name, posName, clickNumber, clickInterval, clickOffset, clickOffsetNumber);

            lst_TskLvl1.Insert(idx,tskLvl1);
        }

        public void RemoveTaskLevel1(int idx)
        {
            lst_TskLvl1.RemoveAt(idx);
        }

        public void MoveTaskLevel1(int idxForm, int idxTo)
        {
            TaskLevel1 tsklvl1 = (TaskLevel1)lst_TskLvl1[idxForm];
            lst_TskLvl1.RemoveAt(idxForm);
            lst_TskLvl1.Insert(idxTo, tsklvl1);
        }

        private TaskLevel1 DuplicateTaskLevel1(TaskLevel1 tsk,string ext)
        {
            TaskLevel1 dupTask = new TaskLevel1();
            dupTask.name = tsk.name + ext;
            dupTask.PosName = tsk.PosName;
            dupTask.ClickNumber = tsk.ClickNumber;
            dupTask.ClickInterval = tsk.ClickInterval;
            dupTask.ClickOffset = tsk.ClickOffset;
            dupTask.ClickOffsetNumber = tsk.ClickOffsetNumber;
            dupTask.clickNumber = tsk.clickNumber;
            dupTask.clickInterval = tsk.clickInterval;
            dupTask.clickOffset = tsk.clickOffset;
            dupTask.clickOffsetNumber = tsk.clickOffsetNumber;
            return dupTask;
        }

        public void CopyTaskLevel1(int idx,string ext)
        {
            lst_TskCopied.Add(DuplicateTaskLevel1((TaskLevel1)lst_TskLvl1[idx],ext));
        }

        public void LoadTaskLevel1(ArrayList arr)
        {
            lst_TskLvl1.AddRange(arr);
        }

        public ArrayList PasteTasksLevel1()
        {
            ArrayList tskLst = new ArrayList();
            foreach (TaskLevel1 tsk1i in lst_TskCopied)
            {
                lst_TskLvl1.Add(tsk1i);
                tskLst.Add(tsk1i.name);
                tskLst.Add(tsk1i.PosName);
            }
            return tskLst;
        }

        private TaskLevel2 CreateTaskLevel2(string name, string arrTskLvl1_Count)
        {
            TaskLevel2 tskLvl2 = new TaskLevel2();
            tskLvl2.name = name;
            tskLvl2.arrTskLvl1 = (ArrayList)lst_TskLvl1;
            tskLvl2.arrTskLvl1_Count = arrTskLvl1_Count;
            int.TryParse(arrTskLvl1_Count, out tskLvl2.arrTskLvl1_count);

            return tskLvl2;
        }

        public void ExportTaskLevel2(string name, string arrTskLvl1_Count)
        {
            TaskLevel2 tskLvl2 = CreateTaskLevel2(name, arrTskLvl1_Count);
            lst_TskLvl1 = new ArrayList();

            lst_TskLvl2.Add(tskLvl2);
        }

        public void ModifyTaskLevel2(int idx, string name, string arrTskLvl1_Count)
        {
            lst_TskLvl2.RemoveAt(idx);
            TaskLevel2 tskLvl2 = CreateTaskLevel2(name, arrTskLvl1_Count);
            lst_TskLvl2.Insert(idx, tskLvl2);
        }

        public void RemoveTaskLevel2(int idx)
        {
            lst_TskLvl2.RemoveAt(idx);
            lst_TskLvl1.Clear();
        }

        public void MoveTaskLevel2(int idxForm, int idxTo)
        {
            TaskLevel2 tsklvl2 = (TaskLevel2)lst_TskLvl2[idxForm];
            lst_TskLvl2.RemoveAt(idxForm);
            lst_TskLvl2.Insert(idxTo, tsklvl2);
        }

        public void LoadTaskLevel2(ArrayList arr)
        {
            lst_TskLvl2.AddRange(arr);
        }

        private TaskLevel2 DuplicateTaskLevel2(TaskLevel2 tsk,string ext)
        {
            TaskLevel2 dupTsk = new TaskLevel2();
            dupTsk.name = tsk.name + ext;
            dupTsk.arrTskLvl1_Count = tsk.arrTskLvl1_Count;
            dupTsk.arrTskLvl1_count = tsk.arrTskLvl1_count;
            dupTsk.arrTskLvl1 = new ArrayList();
            foreach(TaskLevel1 tsk1i in tsk.arrTskLvl1)
            {
                dupTsk.arrTskLvl1.Add(DuplicateTaskLevel1(tsk1i,""));
            }
            return dupTsk;
        }

        public void CopyTaskLevel2(int idx,string ext)
        {
            lst_TskCopied.Add(DuplicateTaskLevel2((TaskLevel2)lst_TskLvl2[idx],ext));
        }

        public ArrayList PasteTasksLevel2()
        {
            ArrayList tskLst = new ArrayList();
            foreach (TaskLevel2 tsk2i in lst_TskCopied)
            {
                lst_TskLvl2.Add(tsk2i);
                tskLst.Add(tsk2i.name);
                tskLst.Add(tsk2i.arrTskLvl1_Count);
            }
            return tskLst;
        }

        private TaskLevel3 CreateTaskLevel3(string name, string arrTskLvl2_Count)
        {
            TaskLevel3 tskLvl3 = new TaskLevel3();
            tskLvl3.name = name;
            tskLvl3.arrTskLvl2 = (ArrayList)lst_TskLvl2;
            tskLvl3.arrTskLvl2_Count = arrTskLvl2_Count;
            int.TryParse(arrTskLvl2_Count, out tskLvl3.arrTskLvl2_count);

            return tskLvl3;
        }

        public void ExportTaskLevel3(string name, string arrTskLvl2_Count)
        {
            TaskLevel3 tskLvl3 = CreateTaskLevel3(name, arrTskLvl2_Count);
            lst_TskLvl2 = new ArrayList();

            lst_TskLvl3.Add(tskLvl3);
        }

        public void ModifyTaskLevel3(int idx, string name, string arrTskLvl2_Count)
        {
            lst_TskLvl3.RemoveAt(idx);
            TaskLevel3 tskLvl3 = CreateTaskLevel3(name, arrTskLvl2_Count);
            lst_TskLvl3.Insert(idx, tskLvl3);
        }

        public void RemoveTaskLevel3(int idx)
        {
            lst_TskLvl3.RemoveAt(idx);
            lst_TskLvl2.Clear();
        }

        public void MoveTaskLevel3(int idxForm, int idxTo)
        {
            TaskLevel3 tsklvl3 = (TaskLevel3) lst_TskLvl3[idxForm];
            lst_TskLvl3.RemoveAt(idxForm);
            lst_TskLvl3.Insert(idxTo, tsklvl3);
        }

        public void LoadTaskLevel3(ArrayList arr)
        {
            lst_TskLvl3.AddRange(arr);
        }

        private TaskLevel3 DuplicateTaskLevel3(TaskLevel3 tsk,string ext)
        {
            TaskLevel3 dupTsk = new TaskLevel3();
            dupTsk.name = tsk.name + ext;
            dupTsk.arrTskLvl2_Count = tsk.arrTskLvl2_Count;
            dupTsk.arrTskLvl2_count = tsk.arrTskLvl2_count;
            dupTsk.arrTskLvl2 = new ArrayList();
            foreach (TaskLevel2 tsk1i in tsk.arrTskLvl2)
            {
                dupTsk.arrTskLvl2.Add(DuplicateTaskLevel2(tsk1i,""));
            }
            return dupTsk;
        }

        public void CopyTaskLevel3(int idx,string ext)
        {
            lst_TskCopied.Add(DuplicateTaskLevel3((TaskLevel3)lst_TskLvl3[idx],ext));
        }

        public ArrayList PasteTasksLevel3()
        {
            ArrayList tskLst = new ArrayList();
            foreach (TaskLevel3 tsk3i in lst_TskCopied)
            {
                lst_TskLvl3.Add(tsk3i);
                tskLst.Add(tsk3i.name);
                tskLst.Add(tsk3i.arrTskLvl2_Count);
            }
            return tskLst;
        }

        private TaskLevel4 CreateTaskLevel4(string name, string arrTskLvl3_Count)
        {
            TaskLevel4 tskLvl4 = new TaskLevel4();
            tskLvl4.name = name;
            tskLvl4.arrTskLvl3 = (ArrayList)lst_TskLvl3;
            tskLvl4.arrTskLvl3_Count = arrTskLvl3_Count;
            tskLvl4.isNormal = int.TryParse(arrTskLvl3_Count, out tskLvl4.arrTskLvl3_count);

            return tskLvl4;
        }

        public void ExportTaskLevel4(string name, string arrTskLvl3_Count)
        {
            TaskLevel4 tskLvl4 = CreateTaskLevel4(name, arrTskLvl3_Count);
            lst_TskLvl3 = new ArrayList();

            lst_TskLvl4.Add(tskLvl4);
        }

        public void ModifyTaskLevel4(int idx, string name, string arrTskLvl3_Count)
        {
            lst_TskLvl4.RemoveAt(idx);
            TaskLevel4 tskLvl4 = CreateTaskLevel4(name, arrTskLvl3_Count);
            lst_TskLvl4.Insert(idx, tskLvl4);
        }

        public void RemoveTaskLevel4(int idx)
        {
            lst_TskLvl4.RemoveAt(idx);
            lst_TskLvl3.Clear();
        }

        public void MoveTaskLevel4(int idxForm, int idxTo)
        {
            TaskLevel4 tsklvl4 = (TaskLevel4)lst_TskLvl4[idxForm];
            lst_TskLvl4.RemoveAt(idxForm);
            lst_TskLvl4.Insert(idxTo, tsklvl4);
        }

        private TaskLevel4 DuplicateTaskLevel4(TaskLevel4 tsk, string ext)
        {
            TaskLevel4 dupTsk = new TaskLevel4();
            dupTsk.name = tsk.name + ext;
            dupTsk.arrTskLvl3_Count = tsk.arrTskLvl3_Count;
            dupTsk.arrTskLvl3_count = tsk.arrTskLvl3_count;
            dupTsk.isNormal = tsk.isNormal;
            dupTsk.arrTskLvl3 = new ArrayList();
            foreach (TaskLevel3 tsk1i in tsk.arrTskLvl3)
            {
                dupTsk.arrTskLvl3.Add(DuplicateTaskLevel3(tsk1i,""));
            }
            return dupTsk;
        }

        public void CopyTaskLevel4(int idx, string ext)
        {
            lst_TskCopied.Add(DuplicateTaskLevel4((TaskLevel4)lst_TskLvl4[idx],ext));
        }

        public ArrayList PasteTasksLevel4()
        {
            ArrayList tskLst = new ArrayList();
            foreach (TaskLevel4 tsk4i in lst_TskCopied)
            {
                lst_TskLvl4.Add(tsk4i);
                tskLst.Add(tsk4i.name);
                tskLst.Add(tsk4i.arrTskLvl3_Count);
            }
            return tskLst;
        }

        public void SaveData()
        {
            FileStream fs = new FileStream(FILENAME, FileMode.Create, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);

            //write datatable
            string data = "";
            foreach (DataRow dr in dt.Rows)
            {
                data = (string)dr[0] + "&" + (string)dr[1] + "^";
                sw.Write(data);
            }

            sw.WriteLine();

            //write login
            sw.WriteLine(tskLoginIdx + "&" + tskLogin.webAddress + "&" + tskLogin.name + "&" + tskLogin.usrName_Pos + "&" +
                tskLogin.usrName + "&" + tskLogin.pass + "&" + tskLogin.login_Pos + "&" + tskLogin.logout_Pos);

            //write tasks
            for (int i= 0; i < lst_TskLvl4.Count; i++)
            {
                if (i == tskLoginIdx) continue;
                TaskLevel4 tskLvl4 = (TaskLevel4)lst_TskLvl4[i];
                sw.Write(tskLvl4.name + "+" + tskLvl4.arrTskLvl3_Count + "+");
                for (int j = 0; j < tskLvl4.arrTskLvl3.Count; j++)
                {
                    TaskLevel3 tskLvl3 = (TaskLevel3)tskLvl4.arrTskLvl3[j];
                    sw.Write(tskLvl3.name + "&" + tskLvl3.arrTskLvl2_Count + "&");
                    for (int k = 0; k < tskLvl3.arrTskLvl2.Count; k++)
                    {
                        TaskLevel2 tskLvl2 = (TaskLevel2)tskLvl3.arrTskLvl2[k];
                        sw.Write(tskLvl2.name + "#" + tskLvl2.arrTskLvl1_Count + "#");
                        for (int l = 0; l < tskLvl2.arrTskLvl1.Count; l++)
                        {
                            TaskLevel1 tskLvl1 = (TaskLevel1)tskLvl2.arrTskLvl1[l];
                            sw.Write(tskLvl1.name + "$" + tskLvl1.PosName + "$" + tskLvl1.ClickNumber + "$" +
                                    tskLvl1.ClickInterval + "$" + tskLvl1.ClickOffset + "$" + tskLvl1.ClickOffsetNumber);
                            sw.Write("!");
                        }
                        sw.Write("%");
                    }
                    sw.Write("^");
                }
                sw.Write("*");
            }

            sw.WriteLine();
            sw.WriteLine(runNumber);
            sw.WriteLine(progSets.taskInterval);
            sw.WriteLine(progSets.clickIntervalDefault);

            sw.Close();
            fs.Close();
        }

        public void LoadData()
        {
            if (!File.Exists(FILENAME)) return;

            FileStream fs = new FileStream(FILENAME, FileMode.Open, FileAccess.Read);
            StreamReader rd = new StreamReader(fs);

            string data = rd.ReadLine();
            
            //load datatable
            string[] dataSplit = data.Split('^');
            for (int i = 0; i < dataSplit.Length - 1; i++)
            {
                string[] elements = dataSplit[i].Split('&');
                Add(elements[0], elements[1]);
            }

            //load login
            data = rd.ReadLine();
            dataSplit = data.Split('&');
            tskLoginIdx = int.Parse(dataSplit[0]);
            tskLogin.webAddress = dataSplit[1];
            tskLogin.name = dataSplit[2];
            tskLogin.usrName_Pos = dataSplit[3];
            tskLogin.usrName = dataSplit[4];
            tskLogin.pass = dataSplit[5];
            tskLogin.login_Pos = dataSplit[6];
            tskLogin.logout_Pos = dataSplit[7];

            //load tasks
            lst_TskLvl1.Clear();
            lst_TskLvl2.Clear();
            lst_TskLvl3.Clear();
            lst_TskLvl4.Clear();

            data = rd.ReadLine();
            string[] dataLvl4 = data.Split('*');
            bool isAddTaskLogin = false;

            for (int i = 0; i < dataLvl4.Length - 1; i++)
            {
                if (i == tskLoginIdx)
                {
                    lst_TskLvl4.Add(tskLogin);
                    isAddTaskLogin = true;
                }
                string[] dataRowLvl4 = dataLvl4[i].Split('+');
                TaskLevel4 tskLvl4 = CreateTaskLevel4(dataRowLvl4[0],dataRowLvl4[1]);

                string[] dataLvl3 = dataRowLvl4[2].Split('^');

                for (int j = 0; j < dataLvl3.Length - 1; j++)
                {
                    string[] dataRowLvl3 = dataLvl3[j].Split('&');
                    TaskLevel3 tskLvl3 = CreateTaskLevel3(dataRowLvl3[0],dataRowLvl3[1]);

                    string[] dataLvl2 = dataRowLvl3[2].Split('%');
                    for (int k = 0; k < dataLvl2.Length - 1; k++)
                    {
                        string[] dataRowLvl2 = dataLvl2[k].Split('#');
                        TaskLevel2 tskLvl2 = CreateTaskLevel2(dataRowLvl2[0],dataRowLvl2[1]);

                        string[] dataLvl1 = dataRowLvl2[2].Split('!');
                        for (int l = 0; l < dataLvl1.Length - 1; l++)
                        {
                            string[] dataRowLvl1 = dataLvl1[l].Split('$');
                            TaskLevel1 tskLvl1 = CreateTaskLevel1(dataRowLvl1[0],dataRowLvl1[1],dataRowLvl1[2],dataRowLvl1[3],dataRowLvl1[4],dataRowLvl1[5]);
                            lst_TskLvl1.Add(tskLvl1);
                        }
                        tskLvl2.arrTskLvl1 = (ArrayList)lst_TskLvl1.Clone();
                        lst_TskLvl1.Clear();
                        lst_TskLvl2.Add(tskLvl2);
                    }
                    tskLvl3.arrTskLvl2 = (ArrayList)lst_TskLvl2.Clone();
                    lst_TskLvl2.Clear();
                    lst_TskLvl3.Add(tskLvl3);
                }
                tskLvl4.arrTskLvl3 = (ArrayList)lst_TskLvl3.Clone();
                lst_TskLvl3.Clear();
                lst_TskLvl4.Add(tskLvl4);
            }

            if (isAddTaskLogin == false && tskLoginIdx == 0)
            {
                lst_TskLvl4.Add(tskLogin);
            }

            runNumber = rd.ReadLine();
            progSets.taskInterval = rd.ReadLine();
            progSets.clickIntervalDefault = rd.ReadLine();

            rd.Close();
            fs.Close();
        }

        public void OpenLog()
        {
            if (!Directory.Exists(LOGFOLDER))
                Directory.CreateDirectory(LOGFOLDER);

            DateTime dt = DateTime.Now;
            currLogDay = dt.Day;
            string fileLogName = LOGFOLDER + "\\" + dt.Day.ToString() + "-" + dt.Month.ToString() + "-" + dt.Year.ToString();
            logFs = new FileStream(fileLogName, FileMode.Append, FileAccess.Write);
            logWr = new StreamWriter(logFs);
        }

        public void CloseLog()
        {
            logWr.Close();
            logFs.Close();
        }

        public void WriteLog(string taskName)
        {
            DateTime dt = DateTime.Now;
            if (currLogDay != dt.Day)
            {
                CloseLog();
                OpenLog();
            }

            string timeLog = dt.Hour.ToString() + ":" + dt.Minute.ToString();
            logWr.WriteLine("[" + taskName + "] " + timeLog);
        }

        public void LoadBlackList()
        {
            if (!File.Exists(BLACKLISTFILENAME)) return ;

            FileStream fs = new FileStream(BLACKLISTFILENAME, FileMode.Open, FileAccess.Read);
            StreamReader rd = new StreamReader(fs);

            while (rd.Peek() >= 0)
            {
                string data = rd.ReadLine();
                //string[] dataSplit = data.Split(',');
                //Color clr = Color.FromArgb(int.Parse(dataSplit[0]), int.Parse(dataSplit[1]), int.Parse(dataSplit[2]), int.Parse(dataSplit[3]));
                //arrBLColor.Add(clr);
                blackListHash.Add(data,data);
            }
            rd.Dispose();
            fs.Dispose();
        }

        public void LoadWhiteList()
        {
            if (!File.Exists(WHITELISTFILENAME)) return;

            FileStream fs = new FileStream(WHITELISTFILENAME, FileMode.Open, FileAccess.Read);
            StreamReader rd = new StreamReader(fs);

            while (rd.Peek() >= 0)
            {
                string data = rd.ReadLine();
                //string[] dataSplit = data.Split(',');
                //Color clr = Color.FromArgb(int.Parse(dataSplit[0]), int.Parse(dataSplit[1]), int.Parse(dataSplit[2]), int.Parse(dataSplit[3]));
                //arrBLColor.Add(clr);
                whiteListHash.Add(data, data);
            }
            rd.Dispose();
            fs.Dispose();
        }

        public int GenerateRandom()
        {
            Random rand = new Random();
            return rand.Next(4, 1000);
        }
    }
}
